var BookmarkStorage = Class.create( //
		{
	initialize : function() {
		this.bookmarkSystems = {};
		try {
			this.bookmarkCache = eval('(' + localStorage['cache'] + ')');
			if (this.bookmarkCache.each) {
				this.bookmarkCache.each(function(item) {
							if (item.time) {
								var timeLit = item.time;
								item.time = new Date();
								item.time.setISO8601(timeLit);
							}
						});
			}
		} catch (e) {
		}
		if (!this.bookmarkCache) {
			this.bookmarkCache = {};
			localStorage['cache'] = Object.toJSON(this.bookmarkCache);
		}
		if (!localStorage['lastUpdated']) {
			this.lastUpdated = new Date(localStorage['lastUpdated']);
		}
	},

	updateBookmark : function(bookmarkInfo, source) {
		if (!bookmarkInfo.urlMD5)
			throw "a bookmark must have a urlMD5!";
		if (this.bookmarkCache[bookmarkInfo.urlMD5]) {
			// already exsists
			var old = this.bookmarkCache[bookmarkInfo.urlMD5];

			if (bookmarkInfo.meta && old.meta
					&& (bookmarkInfo.meta == old.meta))
				return

			if (bookmarkInfo.meta && old.meta
					&& (bookmarkInfo.meta == old.meta))
				return

			if (bookmarkInfo.time && old.time && bookmarkInfo.time < old.time)
				return;

			this.bookmarkCache[bookmarkInfo.urlMD5] = bookmarkInfo;
			subPub.publish('bookmark/updated', [bookmarkInfo, source]);
			this.saveCache();
		} else {
			this.bookmarkCache[bookmarkInfo.urlMD5] = bookmarkInfo;
			subPub.publish('bookmark/created', [bookmarkInfo, source]);
			this.saveCache();
		}
	},

	deleteBookmark : function(urlMD5, source) {
		if (this.bookmarkCache[urlMD5]) {
			var oldBookmark = this.bookmarkCache[urlMD5];
			delete this.bookmarkCache[urlMD5];
			subPub.publish('bookmark/delete', [oldBookmark, source]);
			this.saveCache();
		}
	},

	changeUrl : function(oldUrlMD5, newUrl, source) {
		if (this.bookmarkCache[oldUrlMD5]) {
			this.bookmarkCache[oldUrlMD5].url = newUrl;
			this.bookmarkCache[oldUrlMD5].urlMD5 = MD5(newUrl);
			this.bookmarkCache[this.bookmarkCache[oldUrlMD5].urlMD5] = this.bookmarkCache[oldUrlMD5];
			delete this.bookmarkCache[oldUrlMD5];
			subPub.publish('bookmark/changeUrl', [oldUrlMD5, newUrl, source]);
			this.saveCache();
		}
	},

	changeTag : function(oldUrlMD5, tags, source) {
		if (this.bookmarkCache[oldUrlMD5]) {
			this.bookmarkCache[oldUrlMD5].tags = tags;
			subPub.publish('bookmark/changeTag', [{
								oldUrlMD5 : oldUrlMD5,
								tags : tags,
								source : source
							}]);
			this.saveCache();
		}
	},

	saveCache : function() {
		if (!this.saveCacheJob) {
			this.saveCacheJob = new Job((function() {
						localStorage['cache'] = Object
								.toJSON(this.bookmarkCache);
						localStorage['lastUpdated'] = this.lastUpdated = new Date();
					}).bind(this), 0);
		}
		this.saveCacheJob.replaceSchedule();
	},

	getCache : function() {
		return this.bookmarkCache;
	}
});